
#include "protocol_meter.h"
#include "meter_ql.h"
#include "app_debug_main.h"
#include "interface_ql.h"
#include "program.h"
#include "meter_com.h"
#include "log_main.h"

#ifdef  QL_CLOUD_CLIENT

MeterData_ql  g_mtdata_ql[GUN_NUM];

// 计算当前充电花费
u32 datarecording(u8 gunid,u8 flagStart)
{
    u8 i;
    int minToday;
    int ret=0;
    TDateTime datetime;
    static TDateTime start_datetime[GUN_NUM];
    static u8 lastRateId[]={0,0,0,0,0,0,0,0};
    static  u32 phasekWh[GUN_NUM],phaseStartkWh[GUN_NUM];
    static u8 num_check_kWh[]={0,0,0,0,0,0,0,0};
    u8   rateId;
    u32  cost_elec=0;
    u32  cost_serve=0;
    
    read_current_datetime(&datetime);
    if (flagStart==2)
    {
        sprintf(_tmp_print_str,"gunid=%d出现大电量前一次抄表时间 %02d%02d%02d %02d%02d%02d\r\n",gunid,
                datetime.Year-2000,datetime.Month,datetime.Day,datetime.Hour,datetime.Min,datetime.Sec);
        fs_debug_104(_tmp_print_str);
    }
    
    read_current_datetime(&datetime);
    
    if (flagStart==2)
    {
        sprintf(_tmp_print_str,"gunid=%d出现大电量抄表时间 %02d%02d%02d %02d%02d%02d\r\n",gunid,
                datetime.Year-2000,datetime.Month,datetime.Day,datetime.Hour,datetime.Min,datetime.Sec);
        fs_debug_104(_tmp_print_str);
        return 0;
    }
    
    minToday=datetime.Hour*60+datetime.Min;
    rateId=minToday/30+1;
    
    if (flagStart == 1) { //充电开始
    
        start_datetime[gunid]  = datetime;
        g_mtdata_ql[gunid].startChargingtime = datetime;
        g_mtdata_ql[gunid].endChargingtime= datetime;
        g_mtdata_ql[gunid].charge_duration=0;
        phasekWh[gunid]  = 0; //当前时段开始电量
        phaseStartkWh[gunid]  = g_realData[gunid].kWh[0];
        g_mtdata_ql[gunid].cost_server = 0;
        g_mtdata_ql[gunid].cost_elec=0;
        g_mtdata_ql[gunid].start_soc=0;
        g_mtdata_ql[gunid].end_soc=0;
        for (i = 0; i < 49; i++) {
            g_mtdata_ql[gunid].curkWh[i] = 0;
        }

        for (i = 0; i < 5; i++)
        {
            g_mtdata_ql[gunid].kWhStart[i] = g_realData[gunid].kWh[i];
            g_mtdata_ql[gunid].kWhEnd[i] = g_realData[gunid].kWh[i];;//开始充电时电表示值
        }

        g_uidata->gunmsg[gunid].charge_duration=0;
        g_uidata->gunmsg[gunid].cost_elec=0;
        g_uidata->gunmsg[gunid].cost_server=0;
        g_uidata->gunmsg[gunid].curcostmoney=0;
        g_uidata->gunmsg[gunid].rate=0;
        g_uidata->gunmsg[gunid].curkWh=0;
        g_uidata->gunmsg[gunid].rate_server=0;
        g_uidata->gunmsg[gunid].pw=0;
        
        g_mtdata_ql[gunid].rateid = rateId - 1;
        
        num_check_kWh[gunid]=0;
        
        g_stop_detail[gunid]=0;
        
        lastRateId[gunid] = rateId;
        
        checkMtDataErr(gunid, 1);
        
        if (main_updateMtData != NULL)
        {
            main_updateMtData(gunid, (void*) &g_mtdata_ql[gunid]);
        }
        
        return 0;
    }
    
    //开始新时段
    if(lastRateId[gunid] != rateId)
    {
        g_mtdata_ql[gunid].curkWh[lastRateId[gunid] ] = phasekWh[gunid] +(g_realData[gunid].kWh[0] - phaseStartkWh[gunid]);

        phasekWh[gunid] = g_mtdata_ql[gunid].curkWh[rateId];//当前时段开始电量

        phaseStartkWh[gunid] = g_realData[gunid].kWh[0];
        g_mtdata_ql[gunid].rateid = rateId-1;
        lastRateId[gunid] = rateId;
        ret=1;
    }
    //   printf("当前时段号=%d  电费率=%d 服务费=%d\n",rateId,g_charge_arg[gunid].fee_config.charge_fee[rateId-1],g_charge_arg[gunid].fee_config.service_fee[rateId-1]);

    for(i=0;i<5;i++)
    {
        g_mtdata_ql[gunid].kWhEnd[i] = g_realData[gunid].kWh[i];;//当前电量市值
    }
    
    g_mtdata_ql[gunid].curkWh[rateId] = phasekWh[gunid] +(g_realData[gunid].kWh[0]-phaseStartkWh[gunid]);
    g_mtdata_ql[gunid].curkWh[0] = g_realData[gunid].kWh[0]-g_mtdata_ql[gunid].kWhStart[0];
    g_mtdata_ql[gunid].charge_duration = diff_DateTime_Sec(&start_datetime[gunid] ,&datetime);  // 充电时长 
    g_mtdata_ql[gunid].endChargingtime = datetime;  // 充电结束时间更新 
       
    for (i = 1 ; i < 49; i++)
    {
        //  printf("当前费用计算  g_mtdata_xj[gunid].curkWh[i]=%d g_charge_arg[gunid].fee_config.charge_fee[i-1]=%d\n",(int)g_mtdata_xj[gunid].curkWh[i],(int)g_charge_arg[gunid].fee_config.charge_fee[i-1]);
        cost_elec  += g_mtdata_ql[gunid].curkWh[i] * g_charge_arg[gunid].fee_config.charge_fee[i-1];
        cost_serve += g_mtdata_ql[gunid].curkWh[i] * g_charge_arg[gunid].fee_config.service_fee[i-1];
    }
    
    g_mtdata_ql[gunid].cost_elec   = cost_elec/100;
    g_mtdata_ql[gunid].cost_server = cost_serve/100;
    
    if (pconfig->devtype == DC) {
    
        if (ycdata_main[gunid].dc.MX[2] > 1 && g_mtdata_ql[gunid].start_soc == 0)
        {
            g_mtdata_ql[gunid].start_soc = ycdata_main[gunid].dc.MX[2];
            g_mtdata_ql[gunid].end_soc = ycdata_main[gunid].dc.MX[2];
        }
        else if(ycdata_main[gunid].dc.MX[2] > (u16)g_mtdata_ql[gunid].end_soc)
        {
            if(g_mtdata_ql[gunid].curkWh[0] == 0)   // 总的充电电量 
            {
                sprintf(_tmp_print_str,"gunid=%d出现电量为0 %02d%02d%02d %02d%02d%02d\r\n",gunid,
                        datetime.Year-2000,datetime.Month,datetime.Day,datetime.Hour,datetime.Min,datetime.Sec);
                fs_debug_104(_tmp_print_str);
                
                if(num_check_kWh[gunid] == 0)
                {
                    num_check_kWh[gunid]++;
                }
                else
                {
                    TCUStopChargeProcess(gunid, 14);
                }
            }
            
            g_mtdata_ql[gunid].end_soc = ycdata_main[gunid].dc.MX[2];
        }
    
        printf("当前SOC   ycdata_main[gunid].dc.MX[2]=%d  start=%d  end=%d gunid=%d\r\n",
        (int) ycdata_main[gunid].dc.MX[2],(int)g_mtdata_ql[gunid].start_soc,(int)g_mtdata_ql[gunid].end_soc,gunid);
    }
    
    return  ret;
}

int HandleMeter_ql(u8 meterid, void *pdata)
{
    MeterData_ql  ql_meter_data;
	MeterDataReal *pmt = (MeterDataReal *)pdata;
	static u8 clear_count[8] = {0};	  // delay for clearing the charging data zhouhao 2021-07-13
	int read_ql_meter_ret = 0;
	u8 flag=1;
    
	printf("\r\n111从电表库传来数据  gunid=%d  pmt->mtid=%d",meterid,pmt->mtid);//抄到全部数据项
	
	if(meterid == METER_IN)
	{
		meter_err_state[METER_IN]=0;
		g_realData[meterid] = *pmt;
		return 0;
	}

    u8 stopreason=0;
	int i;
	u8 gunid=pmt->mtid;
	meter_err_state[gunid]=0;
	static u8 flag_first[]={1,1,1,1,1,1,1,1};
	int ret=0;

	printf("\r\n从电表库传来数据  gunid=%d  pmt->mtid=%d",meterid,pmt->mtid);

	if(g_realData[meterid].kWh[0] != pmt->kWh[0])
	{
		flag=1; // 电能发生变化 
	}
	else
	{
		flag=0;
	}
    
    // 系统上电或者电表故障 
	if (flag_first[gunid] == 1 || meter_err_state[gunid]==1 )
	{
		g_realData[gunid] = *pmt;
		if (flag_first[gunid]==1)
		{
			printf("\r\n刚上电   gunid=%d",gunid);
			flag_first[gunid]=0;
			printf("\r\n111刚上电   gunid=%d",gunid);
		}
		else
		{
			printf("上次可能没有抄到表！！！！");
          	sprintf(_tmp_print_str," 上次可能没有抄到表！！！！gunid=%d\n",gunid);
          	fs_debug_104(_tmp_print_str);
		}
	}
	else if ((pmt->kWh[0] - g_realData[gunid].kWh[0]) < 100
			&& pmt->kWh[0] >= g_realData[gunid].kWh[0]) 
    {
		g_realData[gunid] = *pmt;  // 电表数据有效，更新 
    }
	else if (g_realData[gunid].kWh[0] == 0)
	{
		printf("上次可能没有抄到表！！！！");
      	sprintf(_tmp_print_str," 上次可能没有抄到表！！！！gunid=%d\n",gunid);
      	fs_debug_104(_tmp_print_str);
		g_realData[gunid] = *pmt;
	}
	else
	{
		printf("\r\n111从电表库传来数据  gunid=%d",gunid);
		printf("小心，出现大电量 gunid=%d！！！！！！！！！！！！！！！！！！！%d  %d  \r\n",gunid,
				(int) g_realData[gunid].kWh[0], (int) pmt->kWh[0]);

      	sprintf(_tmp_print_str,"小心，出现大电量 gunid=%d！！！！！！！！！！！！！！！！！！！%d  %d  \r\n",gunid,
				(int) g_realData[gunid].kWh[0], (int) pmt->kWh[0]);//故障编号=
      	fs_debug_104(_tmp_print_str);

		datarecording(gunid, 2);
        TCUStopChargeProcess(gunid, 14);
        ql_meter_data.kWhStart[0] =  g_realData[gunid].kWh[0]; 
        
        debug_meter1("g_realData[0].failReadMt=%d  pmt->failReadMt=%  gunid=%d\r\n",
				g_realData[gunid].failReadMt, pmt->failReadMt, gunid);
		return 1;
	}

	meter_err_state[gunid]=0;
	debug_meter1("\r\n处理第%d块表的数据！！！！！！！！！！！g_realData[gunid].read_flag=%x\r\n", gunid,g_realData[gunid].read_flag);
	//	debug_meter1("控制器当前状态 g_uidata->gunmsg[%d].charge_state=%d\r\n",gunid,g_uidata->gunmsg[gunid].charge_state);
	//	ret=getChargeState(gunid);
	// 显示电量
    debug_meter1("当前电压： %d, 电流： %d, 电量: %d", g_realData[gunid].voltage[0], g_realData[gunid].current[0], g_realData[gunid].kWh[0]);
    ql_meter_data.kWhEnd[0] =  g_realData[gunid].kWh[0]; 
	if (gm_sys_state[gunid] == _SYS_START_FIN_ ||
		(gunid == 1 && gm_ctrl_state[0] == _CTRL_COMB_EN_ && gm_sys_state[0] == _SYS_START_FIN_)) //g_uidata->gunmsg[gunid].charge_state==1 &&
	{
		//粤易充		   1.本地刷卡终止，2.远程终止充电，3充满自动停止，4余额不足，5充电桩故障，6 BMS故障，7、急停按钮停止，
		//8.验证码停止，9.停电结束，10.按电量满足结束，11.按金额满足结束，12.按时间满足结束，13.拔枪结束，
		//羊城充			1本地刷卡终止，2远程终止充电，3充满自动停止，4余额不足，5充电桩故障，6 BMS故障   	7、急停按钮停止
		//8充电时间到自动停止 9充电金额到自动停止 10充电电量到自动停止
		for (i = 0; i < 3; i++) {
			g_candata.gun[gunid].yc_in_data.MX[i] = g_realData[gunid].voltage[i];
			g_candata.gun[gunid].yc_in_data.MX[3 + i] = (g_realData[gunid].current[i] + 5) / 10;
			debug_meter1("电压[%d]=%d     %d  电流[%d] =%d  %d\r\n",gunid,g_candata.gun[gunid].yc_in_data.MX[i],(int)g_realData[gunid].voltage[i],
					gunid,g_candata.gun[gunid].yc_in_data.MX[3+i],(int)g_realData[gunid].current[i]);
		}
        
		ret = checkMtDataErr(gunid, 0);
		if (ret > 0) 
        {
			printf("出现计量故障ret=%d！！！！！！！\n", ret);
			sprintf(_tmp_print_str, " 出现计量故障  gunid=%d  ret =%d \n ", gunid, ret);
			fs_debug_104(_tmp_print_str);
			checkMtDataErr(gunid, 1);
		} 
        else if (ret < 0) 
        {
			printf("未能进行计量故障检测ret=%d！！！！！！！\n", ret);
		}
        
        //计算花费
		datarecording(gunid, 0); 

		//	countCost(gunid);
		//g_uidata->gunmsg[gunid].rate = (int) g_charge_arg[gunid].fee_config.charge_fee[g_mtdata_ql[gunid].rateid] * 100; // (g_mtdata[gunid].rate + 5) / 10;
		//g_uidata->gunmsg[gunid].rate_server = (int) g_charge_arg[gunid].fee_config.service_fee[g_mtdata_ql[gunid].rateid] * 100;
		//g_uidata->gunmsg[gunid].pw = g_realData[gunid].Power;

		if (gm_ctrl_state[0] != _CTRL_COMB_EN_) 
        {
			TDateTime datetime;
            
			read_current_datetime(&datetime);
			//g_uidata->gunmsg[gunid].charge_duration = g_mtdata_ql[gunid].charge_duration;

			if (flag == 1) 
            {
				//g_uidata->gunmsg[gunid].curkWh = g_mtdata_ql[gunid].curkWh[0];
				//g_uidata->gunmsg[gunid].curkWh = g_uidata->gunmsg[gunid].curkWh * 10 + datetime.Sec % 10;
			}
            
			//g_uidata->gunmsg[gunid].cost_elec = g_mtdata_ql[gunid].cost_elec;
			//g_uidata->gunmsg[gunid].cost_server = g_mtdata_ql[gunid].cost_server;
			//g_uidata->gunmsg[gunid].curcostmoney = g_mtdata_ql[gunid].cost_elec + g_mtdata_ql[gunid].cost_server;

			//debug_meter1("当前电费率 =%d   当前服务费率=%d",g_uidata->gunmsg[gunid].rate,g_uidata->gunmsg[gunid].rate_server); 
            //debug_meter1("当前费用情况  mode=%d    服务费=%d  电费=%d   电量=%d   设置数值=%d   剩余金额=%d",g_charge_arg[gunid].billmode
			//		     ,g_mtdata_ql[gunid].cost_server,g_mtdata_ql[gunid].cost_elec,g_mtdata_ql[gunid].curkWh[0],g_charge_arg[gunid].value,g_charge_arg[gunid].account_balance);

            // 该功能在青莲云SDK中实现
            /*
			if (g_uidata->gunmsg[gunid].curcostmoney + 100 >= g_charge_arg[gunid].account_balance) 
            {
				stopreason = 4;             // 检查充电费用是否超出账户余额 
			} 
            else if (g_charge_arg[gunid].billmode == 1 && g_uidata->gunmsg[gunid].curkWh >= g_charge_arg[gunid].value)
            {
				stopreason = 10;			//10.按电量满足结束
            }
 			else if (g_charge_arg[gunid].billmode == 2 && ((g_uidata->gunmsg[gunid].charge_duration * 100) / 60) >= g_charge_arg[gunid].value)
 			{
				stopreason = 12;			//8;//12.按时间满足结束 
 			}
 			else if (g_charge_arg[gunid].billmode == 3 && g_uidata->gunmsg[gunid].curcostmoney >= g_charge_arg[gunid].value)
 			{
				stopreason = 11;			//9; 按金额满足结束
 			}

			if (stopreason != 0) 
            {
				debug_meter1("111满足了充电停止条件！！！stopreason=%d gunid=%d",stopreason,gunid);
				TCUStopChargeProcess(gunid, stopreason);
				debug_meter1("222满足了充电停止条件！！！stopreason=%d",stopreason);
			}
			*/
		} 
        else 
        {           
            //共充
			//g_uidata->gunmsg[0].charge_duration = g_mtdata_ql[0].charge_duration;   // 充电时间 
            // 电表无故障 
			if (meter_err_state[0] == 0 && meter_err_state[1] == 0) 
            {
				//g_uidata->gunmsg[0].curkWh = g_mtdata_ql[0].curkWh[0] + g_mtdata_ql[1].curkWh[0];
				//g_uidata->gunmsg[0].cost_elec = g_mtdata_ql[0].cost_elec + g_mtdata_ql[1].cost_elec;
				//g_uidata->gunmsg[0].cost_server = g_mtdata_ql[0].cost_server + g_mtdata_ql[1].cost_server;
				//g_uidata->gunmsg[0].curcostmoney = g_uidata->gunmsg[0].cost_elec + g_uidata->gunmsg[0].cost_server;
			}
            
            //debug_meter("共充：当前电费率 =%d   当前服务费率=%d",g_uidata->gunmsg[0].rate,g_uidata->gunmsg[0].rate_server); 
            //debug_meter1("共充  当前费用情况  mode=%d    服务费=%d  电费=%d   电量=%d   设置数值=%d   剩余金额=%d",g_charge_arg[0].billmode
			//    ,g_mtdata_ql[0].cost_server,g_mtdata_ql[0].cost_elec,g_mtdata_ql[0].curkWh[0],g_charge_arg[0].value,g_charge_arg[0].account_balance);
            // 该功能在青莲云SDK中实现
            /*
			if (g_uidata->gunmsg[0].curcostmoney + 100 >= g_charge_arg[0].account_balance) {
				stopreason = 4;
			} else if (g_charge_arg[0].billmode == 1 && g_uidata->gunmsg[0].curkWh >= g_charge_arg[0].value)
				stopreason = 10;			//10.按电量满足结束
			else if (g_charge_arg[0].billmode == 2 && g_uidata->gunmsg[0].charge_duration * 100 >= g_charge_arg[0].value)
				stopreason = 12;			//8;//12.按时间满足结束
			else if (g_charge_arg[0].billmode == 3 && g_uidata->gunmsg[0].curcostmoney >= g_charge_arg[0].value)
				stopreason = 11;			//9; 按金额满足结束

			if (stopreason != 0) {
				debug_meter1("111共充满足了充电停止条件！！！stopreason=%d gunid=%d",stopreason,0);
				TCUStopChargeProcess(0, stopreason);
				debug_meter1("222共充满足了充电停止条件！！！stopreason=%d",stopreason);
			}
			*/
		}
        
		//	debug_meter1("充电情况下将遥测数据输入到CAN模块中   g_mtdata[gunid].curkWh[0]=%d   时长=%d",g_mtdata[gunid].curkWh[0],g_mtdata[gunid].charge_duration);
		g_candata.gun[gunid].yc_in_data.MX[6] = (g_mtdata_ql[gunid].curkWh[0] + 5) / 10;
		g_candata.gun[gunid].yc_in_data.MX[7] = g_mtdata_ql[gunid].charge_duration;

	}
    else 
    {
		debug_meter1("未充电情况下将遥测数据输入到CAN模块中 gunid=%d",gunid);
		g_candata.gun[gunid].yc_in_data.MX[6] = 0;
		g_candata.gun[gunid].yc_in_data.MX[7] = 0;
	}
    
	g_realData[gunid].failReadMt=0;
    
     if(main_updateMtData != NULL)
     {
         memset((void*)&ql_meter_data, 0, sizeof(MeterData_ql));
         ql_meter_data.kWhEnd[0] =  g_realData[gunid].kWh[0];
         read_ql_meter_ret = main_updateMtData(gunid,(void*) &ql_meter_data);
         if ((read_ql_meter_ret == 2)||(clear_count[gunid] >= 10))	// read data in charging!
         {
			 g_uidata->gunmsg[gunid].cost_elec = ql_meter_data.cost_elec / 10000;	// 10000 * 100, 电量（10000） × 费率（100）
			 g_uidata->gunmsg[gunid].cost_server = ql_meter_data.cost_server / 10000;
			 g_uidata->gunmsg[gunid].curcostmoney = (g_uidata->gunmsg[gunid].cost_elec + g_uidata->gunmsg[gunid].cost_server);
			 g_uidata->gunmsg[gunid].charge_duration = ql_meter_data.charge_duration;  // 分钟
			 g_uidata->gunmsg[gunid].curkWh = ql_meter_data.curkWh[0] / 10;	// 10000 放大1000倍
			 //2021-06-18
			 g_uidata->gunmsg[gunid].rate = ql_meter_data.cur_elec*100;
			 g_uidata->gunmsg[gunid].rate_server = ql_meter_data.cur_servicer*100;
			 clear_count[gunid] = 0;
         }
         else
         {
        	 if (clear_count[gunid] < 10)
        	 {
        		 clear_count[gunid]++;
        	 }
         }
         //debug_meter1("rateid %d,电费费率 rate=%d,服务费率 rate_server=%d",ql_meter_data.rateid,g_uidata->gunmsg[gunid].rate ,g_uidata->gunmsg[gunid].rate_server);
     }
     
     ret=0;
     
     if(main_updateMtDataReal != NULL)
     {
    	 debug_meter1("gun:%d, cur_kwh:%d, p:0x%x", gunid, g_realData[gunid].kWh[0], &g_realData[gunid]);
	 	 ret = main_updateMtDataReal(gunid,(void*)&g_realData[gunid]);
     }

	 if (ret == 1)
	 {
        g_msg_save[gunid] = _MSG_SAVE_CHANGE_;//_MSG_SAVE_CHANGE_NODB;
   		printf("上次上报后电量变化超过0.1 度 \r\n");
	 }
     
	for (i = 0; i < 3; i++) 
    {
		g_candata.gun[gunid].yc_in_data.MX[i] = g_realData[gunid].voltage[i];
		g_candata.gun[gunid].yc_in_data.MX[3 + i] =(g_realData[gunid].current[i]+5)/10;
		debug_meter1("电压[%d]=%d     %d  电流[%d] =%d  %d\r\n",gunid,g_candata.gun[gunid].yc_in_data.MX[i],(int)g_realData[gunid].voltage[i],
		    gunid,g_candata.gun[gunid].yc_in_data.MX[3+i],(int)g_realData[gunid].current[i]);
	}

	debug_meter("处理电表完成！！！！！\r\n");

	return 0;
}


#endif

